home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / origami / oriedt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  9.7 KB  |  455 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #ifdef CONFIG_H
  4. #   include "config.h"
  5. #endif
  6.  
  7. #include <sys/types.h>
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <limits.h>
  11. #include <signal.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14.  
  15. #define ORIEDT_C
  16. #define I_BUFFLOOP_C
  17. #define I_DISPLAY_C
  18. #define I_FINDS_C
  19. #define I_FOLDHELP_C
  20. #define I_FOLDING_C
  21. #define I_GETMSG_C
  22. #define I_GETTK_C
  23. #define I_LOOP_C
  24. #define I_MAIN_C
  25. #define I_MISC_C
  26. #define I_MESSAGES_C
  27. #define I_PROMPT_C
  28. #define I_SCREEN_C
  29. #define I_SIGNALS_C
  30. #define I_STRING_C
  31. #define I_VIRTUAL_C
  32.  
  33. #include "origami.h"
  34. #include <lib/ori_add_lib.h>
  35. /*}}}  */
  36.  
  37.  
  38. /*{{{  size of element-blocks*/
  39. #ifdef VIRTUAL
  40. #  define NEW_ELEMENT_START (vir_nodes?NEW_ELEMENT_MAX:NEW_ELEMENT_LIMIT)
  41. #else
  42. #  define NEW_ELEMENT_START NEW_ELEMENT_LIMIT
  43. #endif
  44. /*}}}  */
  45. /*{{{  variables*/
  46. private element *dispose_tail = &null_element;
  47. #define dispose_head (&null_element)
  48. private boolean warn_mem=True;
  49. /*}}}  */
  50.  
  51. /*{{{  flat_dispose_list*/
  52. private void flat_dispose_list(boolean all)
  53. {
  54.  
  55. #ifdef VIRTUAL
  56.   if (!vir_nodes)
  57. #endif
  58.    { element *p;
  59.  
  60.      for (p=dispose_head;p!=dispose_tail;)
  61.       { p=p->next;
  62.         set_0_data(p);
  63.         if (test_linetyp(*p,(START_FOLD|START_FILED)))
  64.          { element *q;
  65.  
  66.            q = p->x.fold.other_end;
  67.            set_linetyp(*p,NOT_FOLD);
  68.            set_linetyp(*q,NOT_FOLD);
  69.            if (dispose_tail == p)
  70.               dispose_tail = q;
  71.            p->next = p->x.fold.data;
  72.          }
  73.         if (!all)
  74.            break;
  75.      }
  76.    }
  77. }
  78. /*}}}  */
  79. /*{{{  ori_malloc*/
  80. public void *ori_malloc(size_t length)
  81. { void *x;
  82.  
  83.   if (!(x=paket_malloc(length)))
  84.    { flat_dispose_list(True);
  85.      if (!(x=paket_malloc(length)))
  86.       { shrink_history();
  87.         if (!(x=paket_malloc(length)))
  88.          {
  89.            /*{{{  maybe warn*/
  90.            if (warn_mem)
  91.               warn_message(M_NO_MALLOC);
  92.            warn_mem=True;
  93.            /*}}}  */
  94.            /*{{{  clear delete buffers*/
  95.            { int i;
  96.              element **d;
  97.  
  98.              for (i=0,d=deleted_lines;i<UNDEL_LINES;i++,d++)
  99.                 if (*d)
  100.                  { proc_dispose(*d);
  101.                    *d=0;
  102.                  }
  103.            }
  104.            delete_ptr=0;
  105.            /*}}}  */
  106.            flat_dispose_list(True);
  107.            x=paket_malloc(length);
  108.            if (!x)
  109.               ori_abort(~SIGINT);
  110.          }
  111.       }
  112.    }
  113.   return(x);
  114. }
  115. /*}}}  */
  116. /*{{{  spaces                fill a string with spaces*/
  117. public void spaces(unsigned char *s, int l)
  118. {
  119.   for (;l>0;)
  120.    { l--;
  121.      *s++=' ';
  122.    }
  123.   *s=0;
  124. }
  125. /*}}}  */
  126. /*{{{  trailing_spaces*/
  127. public void trailing_spaces(unsigned char *s)
  128. {
  129.   unsigned char *y=s;
  130.  
  131.   for (;;)
  132.    { switch (*s++)
  133.       { default:
  134.            y=s;
  135.         case ' ':
  136.         case '\t':
  137.            continue;
  138.         case '\0':;
  139.       }
  140.      break;
  141.    }
  142.   *y='\0';
  143. }
  144. /*}}}  */
  145. /*{{{  join_links*/
  146. public void join_links(element * const p,element * const q)
  147. {
  148.   p->next = q;
  149.   q->prec = p;
  150.   if (test_linetyp(*p,START_FOLD|START_FILED))
  151.      p->x.fold.other_end->next = q;
  152. }
  153. /*}}}  */
  154. /*{{{  move_on*/
  155. public element *move_on(element const *p)
  156. {
  157.   if (test_linetyp(*p,START_FOLD))
  158.      p=p->x.fold.data;
  159.   else
  160.      p=p->next;
  161.  
  162.   return((element*)p);
  163. }
  164. /*}}}  */
  165. /*{{{  close_fold_at*/
  166. public void close_fold_at(element * const ptr)
  167. {
  168.   element *p;
  169.   int i;
  170.  
  171.   p = ptr;
  172.   /*{{{  start fold ?*/
  173.   if (test_linetyp(*p,START_OPEN_FOLD))
  174.    { set_linetyp(*p,START_FOLD);
  175.      p->x.fold.data = p->next;
  176.      p->next = p->x.fold.other_end->next;
  177.      p->next->prec = p;
  178.    }
  179.   /*}}}  */
  180.   i = p->x.fold.UU.U1.indent;
  181.   p->indent -= i;
  182.   i += p->indent;
  183.   p = p->x.fold.data;
  184.   /*{{{  search matching end-fold*/
  185.   for (;;)
  186.    { switch (get_linetyp(*p))
  187.       { case END_FOLD:
  188.            break;
  189.         case START_OPEN_FOLD:
  190.            close_fold_at(p);
  191.         default:
  192.            p->indent -= i;
  193.            p = p->next;
  194.            continue;
  195.       }
  196.      break;
  197.    }
  198.   /*}}}  */
  199.   p->indent -= i;
  200. }
  201. /*}}}  */
  202. /*{{{  proc_dispose*/
  203. public void proc_dispose(element * const p)
  204. {
  205.   join_links(dispose_tail, p);
  206.   dispose_tail = p;
  207. }
  208. /*}}}  */
  209. /*{{{  proc_new_element*/
  210. public element *proc_new_element(void)
  211. {
  212.   element *n;
  213.  
  214.   if (dispose_head == dispose_tail)
  215.    /*{{{  malloc new space*/
  216.    { static element base_element[BASIC_ELEMENTS];
  217.      static element *el_ptr=base_element;
  218.      static int el_used=BASIC_ELEMENTS;
  219.  
  220.      if (!el_used)
  221.       /*{{{  malloc a new big element's-block*/
  222.       { el_used=NEW_ELEMENT_START;
  223.         el_ptr=0;
  224.         while (el_used && !(el_ptr=ori_malloc(el_used*sizeof(element))))
  225.          { if (dispose_head != dispose_tail)
  226.             { el_used=0;
  227.               goto del_list_usage;
  228.             }
  229.            el_used=el_used>>1;
  230.            warn_mem=False;
  231.          }
  232.         warn_mem=True;
  233.         if (!el_used)
  234.            exit_origami(r_mem_full,M_NO_MEMORY);
  235.       }
  236.       /*}}}  */
  237.      /*{{{  use element in allocated block*/
  238.      n=el_ptr++;
  239.      el_used--;
  240.      /*}}}  */
  241.    }
  242.    /*}}}  */
  243.   else
  244.    /*{{{  use node from list*/
  245.    { del_list_usage:
  246.      flat_dispose_list(False);
  247.      n = dispose_head->next;
  248.      /*{{{  join correct links for dispose-list*/
  249.      if (dispose_tail == n)
  250.         dispose_tail = dispose_head;
  251.      else
  252.         join_links(dispose_head, n->next);
  253.      /*}}}  */
  254.    }
  255.    /*}}}  */
  256.   /*{{{  init data of new element*/
  257.   *n = null_element;
  258.   /*}}}  */
  259.   return(n);
  260. }
  261. /*}}}  */
  262. /*{{{  set_fold_mark_dsp_length*/
  263. public void set_fold_mark_dsp_length(struct f_m_str * const fm)
  264. {
  265.   int i;
  266.  
  267.   for (fm->o_dsp_l=fm->l_dsp_l=2*dsp.norm,i=FOLD_TAG_LENGTH-1;i>=0;i--)
  268.    { fm->o_dsp_l+=char_dsp_size(fm->open_f[i]);
  269.      fm->l_dsp_l+=char_dsp_size(fm->line_f[i]);
  270.    }
  271. }
  272. /*}}}  */
  273. /*{{{  proc_to_edit_pos*/
  274. public void proc_to_edit_pos(void)
  275. {
  276.   int x;
  277.  
  278.   x=bd.f.current->indent*dsp.norm;
  279.   switch(get_linetyp(*bd.f.current))
  280.    { case START_FOLD:
  281.      case START_FILED:
  282.         bd.e.pre_scr_e_pos=x+bd.f.current->x.fold.UU.U1.indent*dsp.norm+1;
  283.         bd.e.first_scr_e_pos=bd.e.pre_scr_e_pos+bd.f.str.l_dsp_l;
  284.         break;
  285.      case START_OPEN_FOLD:
  286.      case START_ENTER_FOLD:
  287.         bd.e.pre_scr_e_pos=0;
  288.         bd.e.first_scr_e_pos=x+1+bd.f.str.o_dsp_l;
  289.         break;
  290.      case END_FOLD:
  291.      case START_ENTER_FILED:
  292.         bd.e.pre_scr_e_pos=0;
  293.         bd.e.first_scr_e_pos=LINELEN+1;
  294.         break;
  295.      default:
  296.         bd.e.pre_scr_e_pos=x-dsp.norm+1;
  297.         bd.e.first_scr_e_pos=x+1;
  298.         break;
  299.    }
  300. }
  301. /*}}}  */
  302. /*{{{  proc_from_edit_pos*/
  303. public void proc_from_edit_pos(void)
  304. {
  305.   if (test_linetyp(*bd.f.current,(START_FOLD|START_FILED)))
  306.    { int i;
  307.  
  308.      /*{{{  i=number of leading spaces*/
  309.      { unsigned char *l;
  310.  
  311.        for (i=0,l=cur_dsp_line;*l==' ';l++,i++);
  312.      }
  313.      /*}}}  */
  314.      bd.f.current->x.fold.UU.U1.indent=i-bd.f.current->indent;
  315.    }
  316. }
  317. /*}}}  */
  318. /*{{{  copyin*/
  319. public void copyin
  320.  ( unsigned char * const line,
  321.    const element * const p,
  322.    const boolean full
  323.  )
  324. {
  325.   /*{{{  variables*/
  326.   const unsigned char *mark_ptr;
  327.   const unsigned char *gap_ptr;
  328.   unsigned char *l_ptr;
  329.   int ind;
  330.   linetyp lt;
  331.   unsigned char *lp;
  332.   /*}}}  */
  333.  
  334.   /*{{{  get data for line*/
  335.   if ((lt=get_linetyp(*p))&END_FOLD)
  336.      if (no_fold_out)
  337.       { *line=0;
  338.         return;
  339.       }
  340.      else
  341.         l_ptr=(unsigned char*)empty_text;
  342.   else
  343.      l_ptr=get_data(p);
  344.   ind = p->indent;
  345.   /*}}}  */
  346.   /*{{{  handle line-typ*/
  347.   switch (lt)
  348.    {
  349.      /*{{{  filed or fold*/
  350.      case START_FOLD:
  351.      case START_FILED:
  352.         if (no_fold_out)
  353.          { mark_ptr=pseudo_mark;
  354.            gap_ptr=two_space;
  355.          }
  356.         else
  357.          { mark_ptr=full?bd.f.str.open_f:bd.f.str.line_f;
  358.            gap_ptr=(lt&START_FILED)?fold_f:two_space;
  359.          }
  360.         ind += p->x.fold.UU.U1.indent;
  361.         break;
  362.      /*}}}  */
  363.      /*{{{  begin fold*/
  364.      case START_OPEN_FOLD:
  365.      case START_ENTER_FOLD:
  366.         if (no_fold_out)
  367.            mark_ptr=pseudo_mark;
  368.         else
  369.            mark_ptr=bd.f.str.open_f;
  370.         gap_ptr=two_space;
  371.         break;
  372.      /*}}}  */
  373.      /*{{{  start enter filed*/
  374.      case START_ENTER_FILED:
  375.         if (no_fold_out)
  376.          { mark_ptr=pseudo_mark;
  377.            gap_ptr=two_space;
  378.          }
  379.         else
  380.          { ind=0;
  381.            mark_ptr=bd.f.str.open_f;
  382.            gap_ptr=fold_f;
  383.          }
  384.         break;
  385.      /*}}}  */
  386.      /*{{{  end fold*/
  387.      case END_FOLD:
  388.         mark_ptr=bd.f.str.close_f;
  389.         gap_ptr=(full && dialects[bd.m.dialect.typ].txt.end[0])?two_space:0;
  390.         break;
  391.      /*}}}  */
  392.      /*{{{  text*/
  393.      case NOT_FOLD:
  394.         mark_ptr=0;
  395.         break;
  396.      /*}}}  */
  397.      default:
  398.         exit_origami(exit_failure,get_msg(F_INT_OCL,STR_INV_FOLD,lt));
  399.    }
  400.   /*}}}  */
  401.   /*{{{  gen indentation spaces, set lp to text-start*/
  402.   for (lp=line;ind>0;ind--)
  403.      *lp++=' ';
  404.   /*}}}  */
  405.   if (mark_ptr)
  406.    /*{{{  append leading-fold-mark/text/trailing-fold-mark*/
  407.    {
  408.      /*{{{  leading comment*/
  409.      if (full)
  410.       { ustrcpy(lp,dialects[bd.m.dialect.typ].txt.start);
  411.         lp+=dialects[bd.m.dialect.typ].lg.start;
  412.       }
  413.      /*}}}  */
  414.      /*{{{  mark*/
  415.      ustrcpy(lp,mark_ptr);
  416.      lp+=FOLD_TAG_LENGTH;
  417.      /*}}}  */
  418.      /*{{{  gap*/
  419.      if (gap_ptr)
  420.       { ustrcpy(lp,gap_ptr);
  421.         lp+=2;
  422.       }
  423.      /*}}}  */
  424.      /*{{{  text*/
  425.      ustrcpy(lp,l_ptr);
  426.      /*}}}  */
  427.      /*{{{  trailing comment*/
  428.      if (full)
  429.         ustrcat(lp,dialects[bd.m.dialect.typ].txt.end);
  430.      /*}}}  */
  431.    }
  432.    /*}}}  */
  433.   else
  434.    /*{{{  append only text*/
  435.      ustrcpy(lp,l_ptr);
  436.    /*}}}  */
  437.   if (full && ind)
  438.      trailing_spaces(line);
  439. }
  440. /*}}}  */
  441. /*{{{  copyout*/
  442. public void copyout(unsigned char const * const line,element * const p)
  443. {
  444.   int i;
  445.   linetyp lt;
  446.  
  447.   i=p->indent;
  448.   if (!((lt=get_linetyp(*p))&NOT_FOLD))
  449.      i+=FOLD_TAG_LENGTH+2;
  450.   if (lt&(START_FOLD|START_FILED))
  451.      i+=p->x.fold.UU.U1.indent;
  452.   set_data(p,strsub(line,i+1),lt&NOT_FOLD);
  453. }
  454. /*}}}  */
  455.